ZYNQ基础

您所在的位置:网站首页 zynq uart1 ZYNQ基础

ZYNQ基础

#ZYNQ基础| 来源: 网络整理| 查看: 265

  在ZYNQ中,串口一般作为打印信息,若想利用串口来传输数据时,可以对串口进行配置。本篇博客介绍串口的中断模式。

串口初始化流程 序号流程函数1查找GPIO配置结构体XUartPs_LookupConfig()2根据结构体初始化GPIOXUartPs_CfgInitialize()3设置波特率 :115200XUartPs_SetBaudRate()4设置操作模式:默认正常模式XUartPs_SetOperMode()5设置接收超时时间XUartPs_SetRecvTimeout()6启动监听XUartPs_Recv() 串口中断注册流程 步骤函数初始化异常处理系统Xil_ExceptionInit();初始化中断控制器XScuGic_LookupConfig()XScuGic_CfgInitialize()注册异常回调函数Xil_ExceptionRegisterHandler()将中断控制器与对应的中断ID相连接XScuGic_Connect()设置UART中断回调函数XUartPs_SetHandler()设置Uart中断类型XUartPs_SetInterruptMask()使能Uart中断XScuGic_Enable()使能异常处理系统Xil_ExceptionEnable() 程序设计

  程序完成的功能是,上位机发送数据给UART,ZYNQ 接收到数据后会触发串口的中断,在串口的中断回调函数中,将接收到的数据发送给上位机。实现一个数据收发的回环。在回调函数中,会对数据进行过滤,只有当接收一帧的数据的前两个字节为0x55时,才会将数据返回给上位机。

#include #include "platform.h" #include "xil_printf.h" #include "xparameters.h" #include "xscugic.h" #include "xuartps.h" #include "sleep.h"#define GIC_DEV_ID XPAR_PS7_SCUGIC_0_DEVICE_ID #define DIST_BASE_ADDR XPAR_PS7_SCUGIC_0_DIST_BASEADDR#define UART_DEV_ID XPAR_PS7_UART_1_DEVICE_ID #define UART_INTR_ID XPAR_PS7_UART_1_INTRstatic XScuGic gicInst; static XScuGic_Config * gicCfg_Ptr;static XUartPs uartInst ; static XUartPs_Config * uartCfg_Ptr;u8 rxBuf[32]; u8 txBuf[32];int initUart() {int status;uartCfg_Ptr = XUartPs_LookupConfig(UART_DEV_ID);status = XUartPs_CfgInitialize(&uartInst, uartCfg_Ptr, uartCfg_Ptr->BaseAddress);if(status != XST_SUCCESS){printf("initialize uart1 failed\n");return XST_FAILURE;}//设置波特率, 115200XUartPs_SetBaudRate(&uartInst, 115200);if(status != XST_SUCCESS){printf("set Buad Rate failed\n");return XST_FAILURE;}//设置操作模式, 默认模式XUartPs_SetOperMode(&uartInst, XUARTPS_OPER_MODE_NORMAL);/** * @param InstancePtr is a pointer to the XUartPs instance.* @param RecvTimeout setting allows the UART to detect an idle connection* on the reciever data line.* Timeout duration = RecvTimeout x 4 x Bit Period. 0 disables the* timeout function.*/XUartPs_SetRecvTimeout(&uartInst, 8);XUartPs_Recv(&uartInst, rxBuf, 32);return XST_SUCCESS; }void uartIntrHandler(void *CallBackRef, u32 Event, u32 EventData) {//接收超时时间发生if(Event == XUARTPS_EVENT_RECV_TOUT){if(EventData == 8 && rxBuf[0] == 0x55 && rxBuf[1] == 0x55){//重新启动监听XUartPs_Recv(&uartInst, rxBuf, 32);XUartPs_Send(&uartInst, rxBuf, 8);}} }int initGic() {int status;//1. 初始化异常处理系统Xil_ExceptionInit();//2. 初始化中断控制器gicCfg_Ptr = XScuGic_LookupConfig(GIC_DEV_ID);status = XScuGic_CfgInitialize(&gicInst, gicCfg_Ptr, gicCfg_Ptr->CpuBaseAddress);if(status != XST_SUCCESS){printf("initialize GIC failed\n");return XST_FAILURE;}//3. 注册异常回调函数Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &gicInst);//4. 连接 Uart1对应的中断IDstatus = XScuGic_Connect(&gicInst, UART_INTR_ID, (Xil_InterruptHandler)XUartPs_InterruptHandler, &uartInst);if(status != XST_SUCCESS){printf("Connect GIC failed\n");return XST_FAILURE;}//5. 设置Uart中断回调函数XUartPs_SetHandler(&uartInst, (XUartPs_Handler)uartIntrHandler, &uartInst);//6. 设置Uart中断类型,timeoutXUartPs_SetInterruptMask(&uartInst, XUARTPS_IXR_TOUT);//7. 使能Uart中断XScuGic_Enable(&gicInst, UART_INTR_ID);//8. 使能异常处理系统Xil_ExceptionEnable();return status; }int main() {int status;//初始化Uartstatus = initUart();if(status != XST_SUCCESS){printf("initialize Uart1 failed\n");return XST_FAILURE;}//初始化GICstatus = initGic();if(status != XST_SUCCESS){printf("initialize GIC failed\n");return XST_FAILURE;}while(1){}return 0; } 实验结果

  最终,从串口上发送数据给到ZYNQ,能够实现,将数据发送回上位机。

在这里插入图片描述

关于回调函数

  在中断设置回调函数时,会使用到函数指针这个变量类型。比如在串口中断中

用于设置串口中断回调的函数:

/****************************************************************************/ /** * * This function sets the handler that will be called when an event (interrupt) * occurs that needs application's attention. * * @param InstancePtr is a pointer to the XUartPs instance * @param FuncPtr is the pointer to the callback function. * @param CallBackRef is the upper layer callback reference passed back * when the callback function is invoked. * * @return None. * * @note * * There is no assert on the CallBackRef since the driver doesn't know what it * is (nor should it) * *****************************************************************************/ void XUartPs_SetHandler(XUartPs *InstancePtr, XUartPs_Handler FuncPtr,void *CallBackRef) {/** Asserts validate the input arguments* CallBackRef not checked, no way to know what is valid*/Xil_AssertVoid(InstancePtr != NULL);Xil_AssertVoid(FuncPtr != NULL);Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);InstancePtr->Handler = (XUartPs_Handler)FuncPtr;InstancePtr->CallBackRef = CallBackRef; }

设置回调函数的用法 串口设置回调函数,其中第二个参数是函数指针类型的变量

XUartPs_SetHandler(&uartInst, (XUartPs_Handler)uartIntrHandler, &uartInst);

回调函数类型定义 函数指针类型的定义如下,根据该类型的定义,在设计用户的回调函数时,需要根据该类型对应的参数来设计。

/******************************************************************************/ /*** This data type defines a handler that an application defines to communicate* with interrupt system to retrieve state information about an application.** @param CallBackRef is a callback reference passed in by the upper layer* when setting the handler, and is passed back to the upper layer* when the handler is called. It is used to find the device driver* instance.* @param Event contains one of the event constants indicating events that* have occurred.* @param EventData contains the number of bytes sent or received at the* time of the call for send and receive events and contains the* modem status for modem events.*******************************************************************************/ typedef void (*XUartPs_Handler) (void *CallBackRef, u32 Event,u32 EventData);

在这里插入图片描述 函数指针类型的使用方法。

//函数指针类型定义 typedef int (*pFunc)(int, int);int add(int a, int b) {return a+b; }int main(int argc, char *argv[]) {pFunc pAdd = add;cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3